package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseSearchDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.dto.QuestionFormDTO;
import com.tianji.learning.entity.InteractionQuestion;
import com.tianji.learning.entity.InteractionReply;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.query.QuestionAdminPageQuery;
import com.tianji.learning.query.QuestionPageQuery;
import com.tianji.learning.service.IInteractionQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.learning.vo.QuestionAdminVO;
import com.tianji.learning.vo.QuestionVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-05-29
 */
@Service
@Slf4j
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    @Autowired
    private SearchClient searchClient;
    @Autowired
    private CourseClient courseClient;
    @Autowired
    private CatalogueClient catalogueClient;
    @Autowired
    private CategoryCache categoryCache;
    @Autowired
    private UserClient userClient;
    @Autowired
    private InteractionReplyMapper interactionReplyMapper;

    /**
     * 新增提问
     *
     * @param questionDTO
     */
    @Override
    public void saveQuestion(QuestionFormDTO questionDTO) {
        //1.获取登录用户
        Long userId = UserContext.getUser();
        //2.封装数据库实体
        InteractionQuestion po = BeanUtils.copyBean(questionDTO, InteractionQuestion.class);
        po.setUserId(userId);
        po.setCreateTime(LocalDateTime.now());
        //3.发起新增sql
        this.save(po);
        //4. TODO 新增问题详情

    }

    /**
     * 分页查询互动问题
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query) {
        //1.获取登录用户信息
        Long userId = UserContext.getUser();
        //2.分页查询
        Page<InteractionQuestion> page = this.lambdaQuery()
                .eq(query.getOnlyMine(), InteractionQuestion::getUserId, userId)
                .eq(InteractionQuestion::getCourseId, query.getCourseId())
                .eq(InteractionQuestion::getCourseId, query.getCourseId())
                .eq(InteractionQuestion::getHidden, false)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());

        List<InteractionQuestion> records = page.getRecords();
        if(CollUtils.isEmpty(records)){
            log.info("问答列表为空！");
            return PageDTO.empty(page);
        }

        //3.获取提问者信息
        //3.2 获取提问者id集合
        Set<Long> ids = new HashSet<>();
        Set<Long> answerIds = new HashSet<>();
        for (InteractionQuestion q : records) {
            if(!q.getAnonymity()) { // 只查询非匿名的问题
                ids.add(q.getUserId());
            }
            answerIds.add(q.getLatestAnswerId());
        }

        //3.3 调用远程接口
        Map<Long, UserDTO> uMap = userClient.queryUserByIds(ids)
                .stream().collect(Collectors.toMap(UserDTO::getId, u -> u));
        //4.封装dto
        List<QuestionVO> voList = new ArrayList<>(records.size())  ;

        //4.2 获取最后一次回答内容
        Map<Long, InteractionReply> reMap = interactionReplyMapper.selectBatchIds(answerIds).stream().collect(Collectors.toMap(InteractionReply::getId, r->r));

        for (InteractionQuestion record : records) {
            QuestionVO vo = BeanUtils.copyBean(record, QuestionVO.class);
            //获取用户
            UserDTO user = uMap.get(record.getUserId());

            vo.setUserName(user.getName());
            vo.setUserIcon(user.getIcon());

            // 4.3.封装最近一次回答的信息
            InteractionReply reply = reMap.get(record.getLatestAnswerId());
            if (reply != null) {
                vo.setLatestReplyContent(reply.getContent());
                if(!reply.getAnonymity()){// 匿名用户直接忽略
                    UserDTO userDto = uMap.get(reply.getUserId());
                    vo.setLatestReplyUser(userDto.getName());
                }

            }
            voList.add(vo);


        }
        return PageDTO.of(page,voList);
    }

    /**
     * 根据id查询问题详情
     *
     * @param id
     * @return
     */
    @Override
    public QuestionVO getInfo(Long id) {
        //1.获取登录用户信息
        InteractionQuestion data = this.getById(id);
        QuestionVO vo = BeanUtils.copyBean(data, QuestionVO.class);
        //2.是否匿名
        if (data.getHidden()) {
            return vo;
        }
        //3.查询用户信息
        UserDTO user = userClient.queryUserById(data.getUserId());
        vo.setUserName(user.getName());
        vo.setUserIcon(user.getIcon());
        log.info("查询id：{}对应数据为：{}",id,vo);
        return vo;
    }

    /**
     * 分页查询互动问题-管理端
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<QuestionAdminVO> queryQuestionAdminPage(QuestionAdminPageQuery query) {
        // 1.处理课程名称，得到课程id
        List<Long> courseIds = null;
        if (StringUtils.isNotBlank(query.getCourseName())) {
            courseIds = searchClient.queryCoursesIdByName(query.getCourseName());
            if (CollUtils.isEmpty(courseIds)) {
                return PageDTO.empty(0L, 0L);
            }
        }
        // 2.分页查询
        Integer status = query.getStatus();
        LocalDateTime begin = query.getBeginTime();
        LocalDateTime end = query.getEndTime();
        Page<InteractionQuestion> page = lambdaQuery()
                .in(courseIds != null, InteractionQuestion::getCourseId, courseIds)
                .eq(status != null, InteractionQuestion::getStatus, status)
                .gt(begin != null, InteractionQuestion::getCreateTime, begin)
                .lt(end != null, InteractionQuestion::getCreateTime, end)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionQuestion> records = page.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }

        // 3.准备VO需要的数据：用户数据、课程数据、章节数据
        Set<Long> userIds = new HashSet<>();
        Set<Long> cIds = new HashSet<>();
        Set<Long> cataIds = new HashSet<>();
        // 3.1.获取各种数据的id集合
        for (InteractionQuestion q : records) {
            userIds.add(q.getUserId());
            cIds.add(q.getCourseId());
            cataIds.add(q.getChapterId());
            cataIds.add(q.getSectionId());
        }
        // 3.2.根据id查询用户
        List<UserDTO> users = userClient.queryUserByIds(userIds);
        Map<Long, UserDTO> userMap = new HashMap<>(users.size());
        if (CollUtils.isNotEmpty(users)) {
            userMap = users.stream().collect(Collectors.toMap(UserDTO::getId, u -> u));
        }

        // 3.3.根据id查询课程
        List<CourseSimpleInfoDTO> cInfos = courseClient.getSimpleInfoList(cIds);
        Map<Long, CourseSimpleInfoDTO> cInfoMap = new HashMap<>(cInfos.size());
        if (CollUtils.isNotEmpty(cInfos)) {
            cInfoMap = cInfos.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, c -> c));
        }

        // 3.4.根据id查询章节
        List<CataSimpleInfoDTO> catas = catalogueClient.batchQueryCatalogue(cataIds);
        Map<Long, String> cataMap = new HashMap<>(catas.size());
        if (CollUtils.isNotEmpty(catas)) {
            cataMap = catas.stream()
                    .collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
        }


        // 4.封装VO
        List<QuestionAdminVO> voList = new ArrayList<>(records.size());
        for (InteractionQuestion q : records) {
            // 4.1.将PO转VO，属性拷贝
            QuestionAdminVO vo = BeanUtils.copyBean(q, QuestionAdminVO.class);
            voList.add(vo);
            // 4.2.用户信息
            UserDTO user = userMap.get(q.getUserId());
            if (user != null) {
                vo.setUserName(user.getName());
            }
            // 4.3.课程信息以及分类信息
            CourseSimpleInfoDTO cInfo = cInfoMap.get(q.getCourseId());
            if (cInfo != null) {
                vo.setCourseName(cInfo.getName());
                vo.setCategoryName(categoryCache.getCategoryNames(cInfo.getCategoryIds()));
            }
            // 4.4.章节信息
            vo.setChapterName(cataMap.getOrDefault(q.getChapterId(), ""));
            vo.setSectionName(cataMap.getOrDefault(q.getSectionId(), ""));
        }
        return PageDTO.of(page, voList);
    }

    /**
     * 根据id查询问题详情--管理端
     *
     * @param id
     * @return
     */
    @Override
    public QuestionAdminVO getInfoAdmin(Long id) {
        //1.根据id查询
        InteractionQuestion data = this.getById(id);
        QuestionAdminVO vo = BeanUtils.copyBean(data, QuestionAdminVO.class);
        //2.获取提问者名称
        UserDTO user = userClient.queryUserById(data.getUserId());
        if (user != null) {
            vo.setUserName(user.getName());
        }
        //3.课程名称
        CourseSearchDTO course = courseClient.getSearchInfo(data.getCourseId());
        vo.setCourseName(course.getName());
        //3.1章节名称
        List<Long> cataList = new ArrayList<>();
        //3.2 老师名称
        UserDTO teacher = userClient.queryUserById(course.getTeacher());
        if (teacher != null) {
            vo.setTeacherName(teacher.getName());
        }
        //3.3 回答数
//        vo.setAnswerTimes();
        //章id
        cataList.add(data.getChapterId());
        //节id
        cataList.add(data.getSectionId());
        List<CataSimpleInfoDTO> catas = catalogueClient.batchQueryCatalogue(cataList);
        Map<Long, String> cataMap = new HashMap<>(catas.size());
        if (CollUtils.isNotEmpty(catas)) {
            cataMap = catas.stream()
                    .collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
        }
        vo.setChapterName(cataMap.getOrDefault(data.getChapterId(), "未查到"));
        vo.setSectionName(cataMap.getOrDefault(data.getSectionId(), "未查到"));
        //3.3分类名称
        List<Long> categoryId = List.of(course.getCategoryIdLv1(), course.getCategoryIdLv2(), course.getCategoryIdLv3());
        vo.setCategoryName(categoryCache.getCategoryNames(categoryId));
        log.info("管理端根据id查询：实体{}",vo);
        return vo;
    }
}
